using AutoMapper;
using DealerPlatform.Common.EventBusHelper;
using DealerPlatform.Common.RedisModule;
using DealerPlatform.Core.Core;
using DealerPlatform.Core.Repository;
using DealerPlatform.Domain;
using DealerPlatform.Service.ShoppingCartApp.Dtos;
using Microsoft.EntityFrameworkCore;

namespace DealerPlatform.Service.ShoppingCartApp;

public partial class ShoppingCartAppService(
    IRepository<ShoppingCart> shoppingCartRepository,
    IMapper mapper,
    LocalEventBus<List<ShoppingCartDto>> localEventBus,
    DealerPlatformContext context,
    IRedisWorker redisWorker,
    RedisCore redisCore)
    : IShoppingCartAppService
{
    public async Task<ShoppingCart> SetShoppingCart(ShoppingCartInputDto input)
    {
        ShoppingCart shoppingCartRes = null;
        // var shoppingCart = await shoppingCartRepository.GetAsync(m => m.ProductNo == input.ProductNo);
        var shoppingCart = redisWorker
            .GetHashMemory<ShoppingCart>($"cart:*:{input.CustomerNo}")
            .FirstOrDefault(m => m.ProductNo == input.ProductNo);
        if (shoppingCart != null)
        {
            shoppingCart.ProductNum++;
            redisWorker.SetHashMemory($"cart:{shoppingCart.CartGuid}:{shoppingCart.CustomerNo}", shoppingCart);
            // shoppingCartRes = await shoppingCartRepository.UpdateAsync(shoppingCart);
        }
        else
        {
            var shoppingcart = mapper.Map<ShoppingCartInputDto, ShoppingCart>(input);
            shoppingcart.CartGuid = Guid.NewGuid().ToString();
            shoppingcart.CartSelected = true;
            // shoppingCartRes = await shoppingCartRepository.InsertAsync(shoppingcart);
            redisWorker.SetHashMemory($"cart:{shoppingcart.CartGuid}:{shoppingcart.CustomerNo}", shoppingcart);
        }

        return shoppingCartRes;
    }

    public async Task<List<ShoppingCartDto>> GetShoppingCartDtos(string customerNo)
    {
        // var shoppingCarts = await shoppingCartRepository.GetListAsync(m => m.CustomerNo == customerNo);
        var shoppingCarts = redisWorker
            .GetHashMemory<ShoppingCart>($"cart:*:{customerNo}");
        var dtos = mapper.Map<List<ShoppingCart>, List<ShoppingCartDto>>(shoppingCarts);
        await localEventBus.Publish(dtos);
        return dtos;
    }

    /// <summary>
    /// 指定更新某个字段
    /// </summary>
    /// <param name="edit"></param>
    /// <returns></returns>
    public async Task<string> UpdateCartSelected(ShoppingCartSelectedEditDto edit, string customerNo)
    {
        if (edit.ProductNum <= 0)
        {
            redisCore.RemoveKey($"cart:{edit.CartGuids[0]}:{customerNo}");
            return "Remove";
        }
        var shoppingCart = redisWorker
            .GetHashMemory<ShoppingCart>($"cart:{edit.CartGuids[0]}:*")
            .FirstOrDefault();
        shoppingCart.CartSelected = edit.CartSelected;
        shoppingCart.ProductNum = edit.ProductNum;
        redisWorker.SetHashMemory($"cart:{edit.CartGuids[0]}:{customerNo}", shoppingCart);
        return "Update";
        // try
        // {
        //     foreach (var cartGuid in edit.CartGuids)
        //     {
        //         ShoppingCart cart = new()
        //         {
        //             CartGuid = cartGuid,
        //             CartSelected = edit.CartSelected,
        //             ProductNum = edit.ProductNum
        //         };
        //         context.Attach(cart);
        //         context.Entry(cart).Property(m => m.CartSelected).IsModified = true;
        //         context.Entry(cart).Property(m => m.ProductNum).IsModified = true;
        //     }
        //
        //     return await context.SaveChangesAsync() > 0;
        // }
        // catch (Exception e)
        // {
        //     return false;
        // }
    }

    /// <summary>
    /// 获取购物车数量
    /// </summary>
    /// <param name="customerNo"></param>
    /// <returns></returns>
    public async Task<int> GetShoppingCartNum(string customerNo)
    {
        var carts = redisWorker
            .GetHashMemory<ShoppingCart>($"cart:*:{customerNo}");
        // var carts = await shoppingCartRepository.GetListAsync(m =>
        //     m.CustomerNo == customerNo && m.CartSelected);
        var currentCartNum = 0;
        carts.ForEach(c => { currentCartNum += c.ProductNum; });
        return currentCartNum;
    }
}